﻿using System;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
using System.Security;
using YZQ_DotNetArx.CAD;
using System.Collections.Generic;

namespace DotNetARX
{
    //#region 第一种封装

    ///// <summary>
    ///// 渐变色填充的图案名称
    ///// </summary>
    //public enum HatchGradientName
    //{
    //    /// <summary>
    //    /// 线状渐变
    //    /// </summary>
    //    Linear,
    //    /// <summary>
    //    /// 圆柱状渐变
    //    /// </summary>
    //    Cylinder,
    //    /// <summary>
    //    /// 反圆柱状渐变
    //    /// </summary>
    //    Invcylinder,
    //    /// <summary>
    //    /// 球状渐变
    //    /// </summary>
    //    Spherical,
    //    /// <summary>
    //    /// 反球状渐变
    //    /// </summary>
    //    Invspherical,
    //    /// <summary>
    //    /// 半球状渐变
    //    /// </summary>
    //    Hemisperical,
    //    /// <summary>
    //    /// 反半球状渐变
    //    /// </summary>
    //    InvHemisperical,
    //    /// <summary>
    //    /// 抛物面状渐变
    //    /// </summary>
    //    Curved,
    //    /// <summary>
    //    /// 反抛物面状渐变
    //    /// </summary>
    //    Incurved
    //}
    ///// <summary>
    ///// 填充图案选项板类
    ///// </summary>
    //public class HatchPalletteDialog
    //{
    //    [SuppressUnmanagedCodeSecurity]
    //    [DllImport("acad.exe", EntryPoint = "?acedHatchPalletteDialog@@YA_NPB_W_NAAPA_W@Z", CharSet = CharSet.Auto)]
    //    static extern bool acedHatchPalletteDialog(string currentPattern, bool showCustom, out IntPtr newPattern);
    //    private string pattern;//用于存储用户选择的填充图案名称
    //    /// <summary>
    //    /// 是否显示自定义标签
    //    /// </summary>
    //    public bool ShowCustom { get; set; }
    //    /// <summary>
    //    /// 获取用户选择的填充图案名称
    //    /// </summary>
    //    /// <returns>返回填充图案名称</returns>
    //    public string GetPattern()
    //    {
    //        return pattern;
    //    }
    //    /// <summary>
    //    /// 构造函数，在填充图案选项板中显示自定义标签
    //    /// </summary>
    //    public HatchPalletteDialog()
    //    {
    //        ShowCustom = true;//显示自定义标签
    //    }
    //    /// <summary>
    //    /// 显示填充图案选项板
    //    /// </summary>
    //    /// <returns>如果用户选择了填充图案，则返回true，否则返回false</returns>
    //    public bool ShowDialog()
    //    {
    //        IntPtr ptr;//用户选择的
    //        //显示填充图案选项板
    //        bool isOK=acedHatchPalletteDialog(HatchTools.CurrentPattern, ShowCustom, out ptr);
    //        if (!isOK) return false;//如果用户未选择填充图案，返回false
    //        //用户选择了填充图案，通过指针获得图案名称并将其置为当前名称
    //        pattern = HatchTools.CurrentPattern = Marshal.PtrToStringAuto(ptr);
    //        return true;
    //    }
    //}
    ///// <summary>
    ///// 填充操作类
    ///// </summary>
    //public static class HatchTools
    //{
    //    /// <summary>
    //    /// 设置或读取默认填充图案，其名称最多可包含 34 个字符，其中不能有空格。
    //    /// </summary>
    //    public static string CurrentPattern
    //    {
    //        //获取HPNAME系统变量值，它表示默认的填充图案名
    //        get { return Application.GetSystemVariable("HPNAME").ToString(); }
    //        set
    //        {
    //            //如果要设置的值符合填充图案名，则设置HPNAME系统变量值
    //            //if (value.Length <= 34 && !value.Contains(" ") && !value.IsNullOrWhiteSpace() && value != CurrentPattern)
    //            //    Application.SetSystemVariable("HPNAME", value);
    //        }
    //    }

    //    /// <summary>
    //    /// 创建图案填充
    //    /// </summary>
    //    /// <param name="hatch">填充对象</param>
    //    /// <param name="patternType">填充图案类型</param>
    //    /// <param name="patternName">填充图案名</param>
    //    /// <param name="associative">填充是否与边界关联</param>
    //    public static void CreateHatch(this Hatch hatch, HatchPatternType patternType, string patternName, bool associative)
    //    {
    //        Database db=HostApplicationServices.WorkingDatabase;
    //        hatch.SetDatabaseDefaults();//设置填充的默认值
    //        //设置填充的类型和填充图案名
    //        hatch.SetHatchPattern(patternType, patternName);
    //        //db.AddToModelSpace(hatch);//将填充添加到模型空间
    //        //设置填充与边界是否关联
    //        hatch.Associative = associative ? true : false;
    //    }
    //    /// <summary>
    //    /// 创建渐变色填充
    //    /// </summary>
    //    /// <param name="hatch">填充对象</param>
    //    /// <param name="gradientName">渐变色填充的图案名称</param>
    //    /// <param name="color1">渐变色填充的起始颜色</param>
    //    /// <param name="color2">渐变色填充的结束颜色</param>
    //    /// <param name="associative">填充是否与边界关联</param>
    //    public static void CreateGradientHatch(this Hatch hatch, HatchGradientName gradientName, Color color1, Color color2, bool associative)
    //    {
    //        //设置渐变色填充的类型所代表的字符串，用于将HatchGradientName枚举转换为对应的字符串
    //        string[] gradientNames=new string[] { "Linear","Cylinder","Invcylinder","Spherical",
    //                                        "Invspherical","Hemisperical","InvHemisperical","Curved","Incurved"};
    //        Database db=HostApplicationServices.WorkingDatabase;
    //        hatch.SetDatabaseDefaults();//设置填充的默认值
    //        //设置填充的类型为渐变色填充
    //        hatch.HatchObjectType = HatchObjectType.GradientObject;
    //        //设置渐变色填充的类型和图案名称
    //        hatch.SetGradient(GradientPatternType.PreDefinedGradient, gradientNames[(int)gradientName]);
    //        //新建两个Color类对象，分别表示渐变色填充的起始和结束颜色
    //        GradientColor gColor1=new GradientColor(color1, 0);
    //        GradientColor gColor2=new GradientColor(color2, 1);
    //        //设置渐变色填充的起始和结束颜色
    //        hatch.SetGradientColors(new GradientColor[] { gColor1, gColor2 });
    //        //db.AddToModelSpace(hatch);//将填充添加到模型空间
    //        Env.AddEntityToModelSpace(hatch);
    //        //设置填充与边界是否关联
    //        hatch.Associative = associative ? true : false;
    //    }
    //}
    //#endregion
    public static class HatchTools
    {
        /// <summary>
        /// 填充图案名称
        /// </summary>
        public readonly struct HatchPatternName
        {
            public static readonly string solid = "SOLID";
            public static readonly string angle = "ANGLE";
            public static readonly string ansi31 = "ANSI31";
            public static readonly string ansi32 = "ANSI32";
            public static readonly string ansi33 = "ANSI33";
            public static readonly string ansi34 = "ANSI34";
            public static readonly string ansi35 = "ANSI35";
            public static readonly string ansi36 = "ANSI36";
            public static readonly string ansi37 = "ANSI37";
            public static readonly string ansi38 = "ANSI38";
            public static readonly string arb816 = "AR-B816";
            public static readonly string arb816c = "AR-B816C";
            public static readonly string arb88 = "AR-B88";
            public static readonly string arbrelm = "AR-BRELM";
            public static readonly string arbrstd = "AR-BRSTD";
            public static readonly string arconc = "AR-CONC";
        }
        /// <summary>
        /// 渐变色填充图案名称
        /// </summary>
        public readonly struct HatchGradientName
        {
            public static readonly string gr_linear = "Linear";
            public static readonly string gr_cylinder = "Cylinder";
            public static readonly string gr_invcylinder = "Invcylinder";
            public static readonly string gr_spherical = "Spherical";
            public static readonly string gr_hemisperical = "Hemisperical";
            public static readonly string gr_curved = "Curved";
            public static readonly string gr_invsperical = "Invspherical";
            public static readonly string gr_invhemisperical = "Invhemispherical";
            public static readonly string gr_invcurved = "Invcurved";
        }
        /// <summary>
        /// 创建图案填充
        /// </summary>
        /// <param name="hatch">填充对象</param>
        /// <param name="patternType">填充图案类型</param>
        /// <param name="patternName">填充图案名</param>
        /// <param name="associative">填充是否与边界关联</param>
        /*
         * HatchPatternType的三个枚举值分别为：
         * UserDefined：用户自定义填充图案类型。这种类型的填充图案需要用户自己编写
         * 代码来实现，可以实现各种复杂的填充效果。
         * PreDefined：预定义填充图案类型。这种类型的填充图案是预先定义好的，可以直
         * 接使用。例如，常见的线条、网格、点状填充等就是预定义的填充图案类型。
         * CustomDefined：自定义填充图案类型。这种类型的填充图案是由用户定义的，但是
         * 与 UserDefined 不同的是，它不需要用户编写代码来实现，而是可以通过一些简单
         * 的操作来创建。例如，用户可以通过选择一些线条或形状来创建自己的填充图案。
         */
        public static void CreateHatch(this Hatch hatch, HatchPatternType patternType, string patternName, bool associative)
        {

            Database db = HostApplicationServices.WorkingDatabase;
            hatch.SetDatabaseDefaults();//设置填充的默认值
            //设置填充的类型和填充图案名
            hatch.SetHatchPattern(patternType, patternName);
            Env.AddEntityToModelSpace(hatch);
            //设置填充与边界是否关联
            hatch.Associative = associative ? true : false;
        }
        /// <summary>
        /// 图案填充
        /// </summary>
        /// <param name="db">图形数据库</param>
        /// <param name="patternName">图案名称</param>
        /// <param name="scale">填充比例</param>
        /// <param name="degree">旋转角度</param>
        /// <param name="bColor">背景色</param>
        /// <param name="hatchColorIndex">填充图案的颜色</param>
        /// <param name="entid">边界图形的ObjectId</param>
        /// <returns>ObjectID</returns>
        public static ObjectId HatchEntity(this Database db, string patternName, double scale, double degree, Color bColor, int hatchColorIndex, ObjectId entid)
        {
            ObjectId hatchId = ObjectId.Null;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                //声明图案填充对象
                Hatch hatch = new Hatch();
                //设置填充比例
                hatch.PatternScale = scale;
                //设置背景色
                hatch.BackgroundColor = bColor;
                //设置填充图案的颜色
                hatch.ColorIndex = hatchColorIndex;
                //设置填充类型和图案名
                hatch.SetHatchPattern(HatchPatternType.PreDefined, patternName);
                //加入图形数据库
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                hatchId = btr.AppendEntity(hatch);
                trans.AddNewlyCreatedDBObject(hatch, true);
                //设置填充角度
                hatch.PatternAngle = degree.DegreeToRadian();
                //设置关联
                hatch.Associative = true;
                //设置边界图形和填充方式
                ObjectIdCollection obIds = new ObjectIdCollection();
                obIds.Add(entid);
                hatch.AppendLoop(HatchLoopTypes.Outermost, obIds);
                //计算填充并显示
                hatch.EvaluateHatch(true);
                //提交事务
                trans.Commit();
            }
            return hatchId;
        }
        /// <summary>
        /// 图案填充多边界
        /// </summary>
        /// <param name="db">图形数据库</param>
        /// <param name="loopTypes">填充边界</param>
        /// <param name="patternName">图案名称</param>
        /// <param name="scale">填充比例</param>
        /// <param name="degree">旋转角度</param>
        /// <param name="bColor">填充背景色</param>
        /// <param name="hatchColorIndex">图案颜色</param>
        /// <param name="entids"></param>
        /// <returns></returns>
        public static ObjectId HatchEntity(this Database db, List<HatchLoopTypes> loopTypes, string patternName, double scale, double degree, params ObjectId[] entids)
        {
            ObjectId hatchId = ObjectId.Null;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                //声明图案填充对象
                Hatch hatch = new Hatch();
                //设置填充比例
                hatch.PatternScale = scale;
                //设置填充类型和图案名
                hatch.SetHatchPattern(HatchPatternType.PreDefined, patternName);
                //加入图形数据库
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                hatchId = btr.AppendEntity(hatch);
                trans.AddNewlyCreatedDBObject(hatch, true);
                //设置填充角度
                hatch.PatternAngle = degree.DegreeToRadian();
                //设置关联
                hatch.Associative = true;
                //设置边界图形和填充方式
                ObjectIdCollection obIds = new ObjectIdCollection();
                for (int i = 0; i < entids.Length; i++)
                {
                    obIds.Clear();
                    obIds.Add(entids[i]);
                    hatch.AppendLoop(loopTypes[i], obIds);
                }
                //计算填充并显示
                hatch.EvaluateHatch(true);
                //提交事务
                trans.Commit();
            }
            return hatchId;
        }
        /// <summary>
        /// 渐变填充
        /// </summary>
        /// <param name="db">图形数据库</param>
        /// <param name="colorIndex1">颜色索引1</param>
        /// <param name="colorIndex2">颜色索引2</param>
        /// <param name="hatchGradientName">渐变图案</param>
        /// <param name="entId">边界图形的ObjectId</param>
        /// <returns>填充图形的ObjectId</returns>
        public static ObjectId HatchGradient(this Database db, short colorIndex1, short colorIndex2, string hatchGradientName, ObjectId entId)
        {
            //声明ObjectId用于返回
            ObjectId hatchId = ObjectId.Null;
            ObjectIdCollection objIds = new ObjectIdCollection();
            objIds.Add(entId);
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                //声明填充对象
                Hatch hatch = new Hatch();
                //设置填充类型为渐变填充
                hatch.HatchObjectType = HatchObjectType.GradientObject;
                //设置渐变填充的类型和图案名称
                hatch.SetGradient(GradientPatternType.PreDefinedGradient, hatchGradientName);
                //设置填充颜色
                Color color1 = Color.FromColorIndex(ColorMethod.ByColor, colorIndex1);
                Color color2 = Color.FromColorIndex(ColorMethod.ByColor, colorIndex2);
                GradientColor gColor1 = new GradientColor(color1, 0);
                GradientColor gColor2 = new GradientColor(color2, 1);
                hatch.SetGradientColors(new GradientColor[] { gColor1, gColor2 });
                //将填充对象加入图形数据库
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                hatchId = btr.AppendEntity(hatch);
                trans.AddNewlyCreatedDBObject(hatch, true);
                //添加关联
                hatch.Associative = true;
                hatch.AppendLoop(HatchLoopTypes.Outermost, objIds);
                //计算并显示填充
                hatch.EvaluateHatch(true);
                //提交事务
                trans.Commit();
            }
            return hatchId;
        }
    }
}